﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;
using System.Xml;

namespace pl.fromsoft.joomla.xmlifg
{
    public class Program
    {
        static void Main(string[] args)
        {

            new Program();

            System.Console.ReadKey();
        }

        private string path = String.Empty;
        private string root = "";
        System.Collections.ArrayList tree = new System.Collections.ArrayList();
        System.Collections.ArrayList xmlitems = new System.Collections.ArrayList();

        static string message;

        public Program()
        {
            root = @"Z:\Proj.Sandbox\_Dev\com_bezbarier\";
            readTree(root);
            saveTreeAsText(@"d:\temp\ftree_log.txt");
            saveXmlitems(@"d:\temp\install.xml");

        }

        public static string getMessage()
        {
            return message;
        }

        /// <summary>
        /// Open session xml file
        /// </summary>
        /// <param name="path">Path to session xml file</param>
        /// <returns>Session form values</returns>
        public static SortedList OpenSession(string path)
        {
            string console = "Debug:";
            SortedList sl = new SortedList();   // SortedList for session form values
            XmlTextReader reader = new XmlTextReader(path);
            if (File.Exists(path))
            {
                while (reader.Read())
                {
                    XmlNodeType nodeType = reader.NodeType;
                    switch (nodeType)
                    {
                        case XmlNodeType.Element:
                            console = string.Format("Element name is {0}", reader.Name);
                            if (reader.HasAttributes)
                            {
                                for (int i = 0; i < reader.AttributeCount; i++)
                                {
                                    reader.MoveToAttribute(i);
                                    console = string.Format("Attribute is {0} with Value {1}: ", reader.Name, reader.Value);
                                    sl.Add(reader.Name, reader.Value);
                                }
                            }
                            break;
                        case XmlNodeType.Text:
                            console = string.Format("Value is: " + reader.Value);
                            break;
                    }
                }
            }
            reader.Close();
            return sl;
        }

        /// <summary>
        /// Save current session
        /// </summary>
        /// <param name="values"></param>
        public static void SaveSession(SortedList values, string path)
        {

            XElement session = new XElement("Session",
                new XAttribute("folder", values["folder"]),
                new XAttribute("name", values["name"]),
                new XAttribute("version", values["version"]),
                new XAttribute("creationdate", values["creationdate"]),
                new XAttribute("author", values["author"]),
                new XAttribute("authoremail", values["authoremail"]),
                new XAttribute("authorurl", values["authorurl"]),
                new XAttribute("copyright", values["copyright"]),
                new XAttribute("license", values["license"]),
                new XAttribute("description", values["description"]),
                new XAttribute("sqlinstall", values["sqlinstall"]),
                new XAttribute("sqluninstall", values["sqluninstall"]),
                new XAttribute("additionalxml", values["additionalxml"])
                        );
          
            TextWriter tw = new StreamWriter(path);
            tw.WriteLine("<!-- Session file created {0} -->", DateTime.Now);
            tw.WriteLine(session.ToString());
            tw.Close();
        }

        /// <summary>
        /// XML build.
        /// </summary>
        /// <param name="values">Values passed by form</param>
        public Program(SortedList values)
        {
            Console.WriteLine("Folder: {0}/nName: {1}/nVersion: {2}/nCreation Date: {3}/nAuthor: {4}/nAuthor Email: {5}/nAuthor URL: {6}/nCopyright: {7}/nLicense: {8}/nDescription: {9}/nAdditional XML: {10}",
                values["folder"], values["name"], values["version"], values["creationdate"],
                values["author"], values["authoremail"], values["authorurl"], values["copyright"],
                values["license"], values["description"], values["additionalxml"]
                );

            root = values["folder"].ToString();
            xmlitems.Add(prepareStandardValues(values));    //  Adds standard joomla header
            readTree(values["folder"].ToString());          //  Adds file informations

            saveXmlitems(@"d:\temp\install.xml");

        }


        /// <summary>
        /// Preparing header standard values
        /// </summary>
        /// <param name="values"></param>
        public String prepareStandardValues(SortedList values)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
            sb.Append("<install type=\"component\" version=\"1.5.0\">\n");

            sb.Append("\n");

            sb.Append("\t<name>" + values["name"] + "</name>\n");
            sb.Append("\t<creationDate>" + values["creationdate"] + "</creationDate>\n");
            sb.Append("\t<author>" + values["author"] + "</author>\n");
            sb.Append("\t<authorEmail>" + values["authoremail"] + "</authorEmail>\n");
            sb.Append("\t<authorUrl>" + values["authorurl"] + "</authorUrl>\n");
            sb.Append("\t<copyright>" + values["copyright"] + "</copyright>\n");
            sb.Append("\t<license>" + values["license"] + "</license>\n");
            sb.Append("\t<version>" + values["version"] + "</version>\n");
            sb.Append("\t<description>" + values["description"] + "</description>\n");

            sb.Append("\n");

            // Install section        	
            sb.Append("<install>\n");
            sb.Append("\t<sql>\n");
            sb.Append("\t\t<file charset=\"utf8\" driver=\"mysql\">" + values["sqlinstall"] + "</file>\n");
            sb.Append("\t</sql>\n");
            sb.Append("</install>\n");
            sb.Append("<uninstall>\n");
            sb.Append("\t<sql>\n");
            sb.Append("\t\t<file charset=\"utf8\" driver=\"mysql\">" + values["sqluninstall"] + "</file>\n");
            sb.Append("\t</sql>\n");
            sb.Append("</uninstall>\n");

            sb.Append(values["additionalxml"] + "\n");

            sb.Append("\n");

            return sb.ToString();

        }

        private void saveXmlitems(string filepath)
        {
            StreamWriter sw = new StreamWriter(filepath, false, Encoding.UTF8);
            foreach (var item in xmlitems)
            {
                sw.WriteLine(item.ToString());
            }
            sw.Close();
            message = "Install.xml saved. Filepath: " + filepath;
        }

        /// <summary>
        /// Save gained information to text file
        /// </summary>
        /// <param name="filepath">Path to text file</param>
        private void saveTreeAsText(string filepath)
        {

            StreamWriter sw = new StreamWriter(filepath, false, Encoding.UTF8);
            sw.WriteLine("[fstree]");
            foreach (var item in tree)
            {
                sw.WriteLine(item.ToString());
            }
            sw.Close();
        }

        /// <summary>
        /// Read content from directories and sub-dirs
        /// </summary>
        /// <param name="dir_path"></param>
        private void readTree(string dir_path)
        {
            DirectoryInfo di = new DirectoryInfo(dir_path);
            readFiles(di.FullName);
            foreach (DirectoryInfo item in di.GetDirectories())
            {
                if (item.Name.ToLower() == "admin" || item.Name.ToLower() == "site")
                    xmlitems.Add("<files folder=" + '"' + item.Name + '"' + '>');
                readTree(item.FullName);
                if (item.Name.ToLower() == "admin" || item.Name.ToLower() == "site")
                    xmlitems.Add("</files>");
            }
        }

        /// <summary>
        /// Read files from directory
        /// </summary>
        /// <param name="dir_path">Directory path</param>
        private void readFiles(string dir_path)
        {
            DirectoryInfo di = new DirectoryInfo(dir_path);
            foreach (FileInfo item in di.GetFiles("*"))
            {
                System.Console.WriteLine(item.FullName);

                // remove root path
                string itemShort = item.FullName;
                itemShort = itemShort.Replace(root, "");

                // cut admin or site folder name
                itemShort = itemShort.Substring(5);
                if (itemShort.StartsWith(@"\")) itemShort = itemShort.Substring(1);

                // replace fileseparator to ux standard
                itemShort = itemShort.Replace(@"\", @"/");

                xmlitems.Add("\t<filename>" + itemShort + "</filename>");
                tree.Add(item.FullName);
            }
        }

        /// <summary>
        /// Read sub-directories from directory
        /// </summary>
        /// <param name="dir_path">Directory path</param>
        private void readDirs(string dir_path)
        {
            DirectoryInfo di = new DirectoryInfo(dir_path);

            foreach (DirectoryInfo item in di.GetDirectories("*"))
            {
                tree.Add(item.FullName);
                System.Console.WriteLine(item.FullName);
            }


        }
    }
}
